<?php

namespace paymch\models;

use Yii;
use yii\db\Exception;
use common\models\trade\Trade;
use common\models\course\CourseOrder;
use common\models\shop\OrderLog as ShopOrderLog;
use common\models\shop\ShopGoodsStatistic;
use common\models\trade\TradeRefund as TableTradeRefund;
use common\helpers\Utils;
use common\models\shop\OrderRefund;
use common\models\trade\TradeOrder;
use common\helpers\Curl;
use common\models\course\CourseGroup;
use common\models\trade\Partner;

/**
 * 交易成功后异步通知业务处理
 * BusinessNotify
 *
 * @author emhome <emhome@163.com>
 * @since 2.0
 */
class BusinessNotify extends BasePaymentModel {

    public $id;
    private $_partner = null;
    private $_trade = null;

    /**
     * Creates a form model given a token.
     * @param string $id
     * @param array $config name-value pairs that will be used to initialize the object properties
     * @throws \yii\base\InvalidParamException if token is empty or not valid
     */
    public function __construct($id = null, $config = []) {
        parent::__construct($config);
        if ($id !== null) {
            $this->_trade = Trade::findOne($id);
        }
    }

    /**
     * 获取交易信息
     * @return \common\models\trade\Trade|null
     */
    protected function getTrade() {
        return $this->_trade;
    }

    /**
     * 交易保存
     */
    public function save(&$msg) {
        $trade = $this->trade;
        if ($trade == null) {
            $msg = '未查询到交易信息';
            return false;
        }
        if ($trade->status !== Trade::STATUS_SUCCESS) {
            $msg = '未成功交易。当前交易状态为：【' . $trade->status . '】';
            return false;
        }
        if ($trade->partner_id == 1 || $trade->partner_id == 2) {
            if ($trade->balance == Trade::BALANCE_PAYMENT) {
                //课程支付回调
                return $this->notifyCourse($msg);
            } else if ($trade->balance == Trade::BALANCE_REDUCE) {
                //课程退款回调
                return $this->notifyFinance($msg);
            }
        }
        $msg = '通知失败，啥都没干...';
        return false;
    }

    /**
     * 商城业务更新
     * @param \common\models\trade\Trade|null $trade
     */
    private function notifyCourse(&$msg) {
        $trade = $this->trade;
        $busorder = CourseOrder::findByOrderNo($trade->bizno);
        if ($busorder == null) {
            $msg = '课程报名订单【' . $trade->bizno . '】不存在！';
            return false;
        }
        if ($busorder->status == CourseOrder::STATUS_DEFAULT) {
            $busorder->out_trade_no = $trade->trade_no;
            $busorder->pay_time = $trade->updated_at;
            $busorder->pay = $trade->total;
            $busorder->status = CourseOrder::STATUS_PAID;
        }
        if (!$busorder->save()) {
            Yii::error($busorder->errors, 'payment');
            $msg = '商城业务订单保存失败！';
            return false;
        }
        //加入当前课程群聊
        CourseGroup::joinByCourse($busorder->user_id, $busorder->course_id);

        return true;
    }

    /**
     * 财务业务更新（退款）
     * ============================
     * ShopOrder  业务订单表
     * TradeRefund 交易退款
     * ShopOrderRefund 商城退款
     * ShopLog 订单日志表
     * ============================
     * @param $trade
     * @return bool
     */
    private function notifyFinance(&$msg) {
        $trade = $this->trade;

        $finished_time = 86400 * 7;   //超时时间
        $time = time();

        //退款成功后回调给交易中心的内容，处理退款业务内容
        $historyTradeOrder = TradeOrder::findOne(['trade_id' => $trade->id]);
        $payTrade = Trade::findOne(['trade_no' => $historyTradeOrder->original_no]);
        $busorder = ShopOrder::findByBizno($payTrade->bizno);
        if ($busorder == null) {
            $msg = sprintf('退款时商城订单【%s】查询失败', $payTrade->bizno);
            return false;
        }

        if (!in_array($busorder->status, [ShopOrder::STATUS_REFUND, ShopOrder::STATUS_FINISHED])) {
            $msg = sprintf('退款时商城订单状态已变更。当前状态【%d】', $busorder->status);
            return false;
        }

        $orderRefund = OrderRefund::findOne(['refund_no' => $trade->bizno]);
        if ($orderRefund == null) {
            $msg = sprintf('退款订单【OrderRefund】【%s】未查询到。', $trade->bizno);
            return false;
        }
        //是否是全额退款
        $refundType = $orderRefund->refund_type == OrderRefund::REFUND_TYPE_PARTIAL ? false : true;

        /**
         * 状态
         * finish_time > 0  已超时订单
         * 全部数量 finish 订单完成
         * 签收+超时+部分数量 finish 订单完成
         * 签收+未超时+部分数量 confirm 确认收货
         * 未签收+已支付+部分数量 success 已支付
         */
        if (!$busorder->finish_time) {
            if ($refundType) {
                $busorder->finish_time = $time;
                $busorder->status = ShopOrder::STATUS_FINISHED;
            } else {
                $busorder->status = ShopOrder::STATUS_CONFIRM;
            }
        } else {
            $busorder->status = ShopOrder::STATUS_FINISHED;
            Yii::info("\n" . '订单[' . $busorder->order_no . ']超时后推送的退款回调消息', 'payment');
        }

        $transaction = Yii::$app->db->beginTransaction();
        try {
            //订单保存
            if (!$busorder->save()) {
                throw new Exception('商城业务订单保存失败！' . Utils::arrayToString($busorder->errors, true));
            }

            //交易中心退款申请表
            $tradeRefund = TableTradeRefund::findOne(['refund_no' => $trade->bizno]);
            $tradeRefund->verify_time = $time;
            $tradeRefund->trade_no = $trade->trade_no;
            $tradeRefund->trade_id = $trade->id;
            $tradeRefund->status = TableTradeRefund::STATUS_SUCCESS;
            if (!$tradeRefund->save()) {
                throw new Exception('交易中心退款申请表保存失败！' . Utils::arrayToString($tradeRefund->errors, true));
            }

            //商城退款申请表
            $orderRefund->refund_money_time = $time;
            $orderRefund->out_trade_no = $trade->trade_no;
            if (!$orderRefund->save()) {
                throw new Exception('商城退款申请单保存失败！' . Utils::arrayToString($orderRefund->errors, true));
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $msg = $e->getMessage();
            Yii::error("\n" . \yii\helpers\VarDumper::export($e->getMessage()), 'payment');
            return false;
        }
        //日志
        $busorderLog = new ShopOrderLog();
        $busorderLog->user_id = $trade->user_id;
        $busorderLog->action = ShopOrderLog::ACTION_REFUND_TRADE_FINISH;
        $busorderLog->order_id = $busorder->id;
        $busorderLog->is_admin = 0;
        $busorderLog->is_show = 1;
        $busorderLog->mask = '订单退款成功';
        if (!$busorderLog->save()) {
            $msg .= '商城订单日志保存失败';
            Yii::error("\n" . Utils::arrayToString($busorderLog->errors, true), 'payment');
        }
        return true;
    }

}
